package cn.donting.jme.edit.ui.inspector;

import cn.donting.jme.edit.annotation.Nullable;
import cn.donting.jme.edit.attribute.Attribute;
import cn.donting.jme.edit.event.EventListener;
import cn.donting.jme.edit.event.EventManager;
import cn.donting.jme.edit.event.SelectSpatialEvent;
import cn.donting.jme.edit.ex.AutoAttributeLoader;
import cn.donting.jme.edit.ex.InspectorUILoader;
import cn.donting.jme.edit.ex.ExResourcesLoad;
import cn.donting.jme.edit.scene.ControlAttributesMapper;
import cn.donting.jme.edit.scene.ControlMapper;
import cn.donting.jme.edit.scene.SpatialControlMapper;
import cn.donting.jme.edit.ui.inspector.imp.base.BaseInfoController;
import cn.donting.jme.edit.ui.inspector.imp.transform.TransformController;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;

@Slf4j
public class InspectorView implements Initializable, EventListener<SelectSpatialEvent> {

    @FXML
    public VBox vBox;

    @FXML
    public ScrollPane scrollPane;

    private static InspectorView inspectorView;

    public Spatial nowSpatial;


    public static InspectorView getInstance() {
        return inspectorView;
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        inspectorView = this;
        EventManager.registerListener(SelectSpatialEvent.class, this);
        scrollPane.widthProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                vBox.setPrefWidth(newValue.doubleValue() - 15);
            }
        });
    }

    /**
     * 更新需要显示的spatial
     *
     * @param spatial 允许空
     */
    public void update(@Nullable Spatial spatial) {
        vBox.getChildren().clear();
        if (spatial == null) {
            return;
        }
        creatBaseInfoInspector(spatial);
        List<InspectorUILoader> inspectorUILoaders = ExResourcesLoad.getInspectorUILoader();
        try {
            for (InspectorUILoader uiLoader : inspectorUILoaders) {
                List<InspectorUI> inspectorUIs = uiLoader.getInspectorUI(spatial);
                for (InspectorUI inspectorUI : inspectorUIs) {
                    HBox hBox = new HBox();
                    TitledPane titledPane = new TitledPane();

                    InspectorContextMenu contextMenu = new InspectorContextMenu();
                    titledPane.setContextMenu(contextMenu);

                    titledPane.setText(inspectorUI.title);
                    if (inspectorUI.icon != null) {
                        hBox.getChildren().add(inspectorUI.icon);
                    }
                    if (inspectorUI.isShowEnable()) {
                        hBox.getChildren().add(inspectorUI.checkBox);
                    }
                    titledPane.setGraphic(hBox);
                    titledPane.setContent(inspectorUI.getUiNode());
                    vBox.getChildren().add(titledPane);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建 基本信息的Inspector
     *
     * @param spatial
     */
    private void creatBaseInfoInspector(Spatial spatial) {
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getClassLoader().getResource("cn/donting/jme/edit/ui/inspector/imp/base/BaseInfo.fxml"));
            Node uiNode = fxmlLoader.load();
            BaseInfoController controller = fxmlLoader.getController();
            controller.setSpatial(spatial);
            vBox.getChildren().add(uiNode);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }


    public void addController(Control control) {
        ControlMapper controlMapper = nowSpatial.getUserData(ControlMapper.key);
        if (controlMapper == null) {
            controlMapper = new ControlMapper();
            nowSpatial.setUserData(ControlMapper.key, controlMapper);
        }
        controlMapper.addController(control);
    }


    @Override
    public void event(SelectSpatialEvent event) {
        nowSpatial = event.getSpatial();
        this.update(event.getSpatial());
    }

}
